package com.yinxing.framework.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.yinxing.framework.constant.SysConstant;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class JwtUtils {

    /**
     * 校验token是否正确
     * @param token 密钥
     * @param secret 用户的密码
     * @return 是否正确
     */
    public static boolean verify(String token, String secret) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm).build();
            verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     * @param token jwt-token
     * @param key 用户数据的key
     * @return 用户数据value
     */
    public static String getValue(String token, String key) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim(key).asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 生成JWT-TOKEN
     * @param data 用户数据
     * @param secret JWT秘钥
     * @param expireTimeMinutes token过期时间
     * @return 加密的token
     */
    public static String sign(Map<String, String> data, String secret, long expireTimeMinutes) {
        Date date = new Date(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(expireTimeMinutes));
        Algorithm algorithm = Algorithm.HMAC256(secret);
        JWTCreator.Builder builder = JWT.create().withExpiresAt(date);
        for (Map.Entry<String, String> entry: data.entrySet()) {
            builder.withClaim(entry.getKey(), entry.getValue());
        }
        return builder.sign(algorithm);
    }

    /**
     * 生成JWT-TOKEN
     * @param userId 用户ID
     * @param secret JWT秘钥
     * @param expireTimeMinutes token过期时间
     * @return 加密的token
     */
    public static String sign(String userId, String secret, long expireTimeMinutes) {
        Map<String, String> data = new LinkedHashMap<>();
        data.put(SysConstant.JWT_TOKEN_DATA_USERID, userId);
        String jwtToken = JwtUtils.sign(data, secret, expireTimeMinutes);
        return jwtToken;
    }
}
